#ifndef CONTAINER_H
#define CONTAINER_H
#include "Box.h"
#include "Point.h"
#include "Bmp.h"

#include <vector>
#include <memory>
#include <algorithm>

enum Align // align标记
{
    TOP_LEFT,
    TOP_CENTER,
    TOP_RIGHT,
    LEFT_CENTER,
    CENTER,
    RIGHT_CENTER,
    BOTTOM_LEFT,
    BOTTOM_CENTER,
    BOTTOM_RIGHT
};

enum Event_Type // 事件类型
{
    NO_EVENT,  // 无事件
    CLICK,     // 点击事件（按下并松开）
    PRESS,     // 按下事件（立即触发）
    LONG_PRESS // 长按事件（可以后续扩展）
};

class Container : public Box
{
protected:
    Container *parent = nullptr;                // 父容器指针
    vector<Container *> sons;                   // 子容器数组
    Point pos;                                  // 坐标
    unsigned int background_color = 0x00000000; // 背景颜色
    bool isUpdata = true;                       // 容器内容更新

    // 控件开关
    Event_Type Click_Type = NO_EVENT;           // 容器的点击事件类型
    bool Visible = false;                       // 容器是否显示
    unique_ptr<Bmp> background_image = nullptr; // 背景图片
    bool background_color_enabled = false;      // 背景颜色开关
    void (*Event)() = nullptr;                  // 声明回调函数

public:
    Container(int width = 800, int height = 480) : Box(width, height)
    {
        store = new int[height * width];
        if (store == nullptr)
        {
            throw std::invalid_argument("Error: Failed to initialize container");
        }
        for (int i = 0; i < height * width; ++i)
        {
            store[i] = 0x00FFFFFF; // 白色背景
        }
    }

    Container(Container *parent)
    {
        if (parent == nullptr)
        {
            throw std::invalid_argument("Parent container cannot be null");
        }
        this->parent = parent;
        this->width = parent->get_width();
        this->height = parent->get_height();

        store = new int[this->height * this->width];
        if (store == nullptr)
        {
            throw std::invalid_argument("Error: Failed to initialize container");
        }
        for (int i = 0; i < height * width; ++i)
        {
            store[i] = 0x00FFFFFF; // 白色背景
        }
        parent->addSon(this);
    }
    Container(Container *parent, int width, int height, int pos_x = 0, int pos_y = 0, int insertIndex = -1)
    {
        if (parent == nullptr)
        {
            throw std::invalid_argument("Parent container cannot be null");
        }

        this->parent = parent;
        this->width = width;
        this->height = height;

        pos.set_pos_x(pos_x);
        pos.set_pos_y(pos_y);

        store = new int[height * width];
        if (store == nullptr)
        {
            throw std::invalid_argument("Error: Failed to initialize container");
        }
        for (int i = 0; i < height * width; ++i)
        {
            store[i] = 0x00FFFFFF; // 白色白色背景
        }

        if (insertIndex == -1)
        {
            parent->addSon(this); // 默认添加到末尾
        }
        else
        {
            parent->addSonAt(this, insertIndex); // 添加到指定位置
        }
    }
    ~Container()
    {
        if (store != nullptr)
        {
            delete[] store;
            store = nullptr;
        }
        cout << "容器被析构" << endl;
        sons.clear();
    }

    // 删除拷贝构造函数和赋值运算符
    Container(const Container &other) = delete;
    Container &operator=(const Container &other) = delete;

    void Trigger_event();

    // 更新当前容器及其所有子容器
    void update();
    void renderTo(int *target, int targetWidth, int targetHeight,
                  int offsetX = 0, int offsetY = 0); // 统一渲染方法

    // 返回函数
    bool isUpdataStore() { return isUpdata; };                          // 检查store是否被更新
    bool hasEvent() const { return Event != nullptr; }                  // 检查是否有事件
    bool isIniBackgroundImage() { return background_image != nullptr; } // 检查有无背景图片
    bool isVisible() { return Visible; }                                // 返回容器是否可显示
    bool isTouch(Point &touch);                                         // 检查是否被点击

    int get_son_count() { return sons.size(); } // 返回子类容器的个数
    int get_Click_Type() { return Click_Type; } // 返回容器是否可被点击
    int get_pos_x() { return pos.get_pos_x(); } // 获取容器x坐标
    int get_pos_y() { return pos.get_pos_y(); } // 获取容器y坐标

    Container *getTouchedContainer(Point &touch); // 返回哪个容器被点击 纵深查找
    Container *getParent() { return parent; }     // 返回父容器指针
    Container *getSon(size_t index);              // 返回子容器实例

    void addSonAt(Container *son, size_t index); // 添加子容器到索引位置
    void removeSon(Container *son);              // 删除子容器
    void Hide_background_image();                // 隐藏背景图片
    void Display_background_image();             // 显示背景图片

    // 控件设置
    void updata_store() { isUpdata = true; } // 更新store
    void set_pos(const int &x, const int &y);
    void set_pos_x(const int &x);
    void set_pos_y(const int &y);                                                                                // 设置容器坐标
    void set_background_color(unsigned int color = 0x00000000);                                                  // 设置背景颜色
    void set_background_image(const char *path, bool isHyaline = false, unsigned int Excludecolor = 0x00000000); // 设置背景图片
    void set_Visible(bool Status = true);                                                                        // 设置可见状态
    void set_Event_Type(Event_Type Click_Type);                                                                  // 设置可点击状态                                                                     // 设置可触碰状态
    void addSon(Container *son);                                                                                 // 添加子容器
    void set_Event(void (*Event)() = nullptr);                                                                   // 设置回调函数
    void align(Align status, int offsetX = 0, int offsetY = 0);                                                  // 设置相对位置

private:
    void renderSelf(); // 自我刷新store数据
};

#endif
